import torch
from typing import Literal


def create_vector(size: tuple, dtype=torch.float) -> torch.Tensor:
    return torch.empty(size, dtype=dtype)


def create_random_vector(size: tuple, distribution: Literal['uniform', 'normal']='uniform', dtype=torch.float) -> torch.Tensor:
    assert distribution in ['uniform', 'normal']
    if distribution == 'uniform':
        return torch.rand(size, dtype=dtype)
    elif distribution == 'normal':
        return torch.randn(size, dtype=dtype)


def create_zero_vector(size: tuple, dtype=torch.float) -> torch.Tensor:
    return torch.zeros(size, dtype=dtype)


def create_scalar_vector(size: tuple, scalar, dtype=torch.float) -> torch.Tensor:
    return torch.full(size, scalar, dtype=dtype)


def create_identity_matrix(n: int, dtype=torch.float) -> torch.Tensor:
    return torch.eye(n, dtype=dtype)


def create_diag_matrix(diag_values: list, dtype=torch.float) -> torch.Tensor:
    x = torch.tensor(diag_values, dtype=dtype)
    return torch.diag(x)


def create_scalar_triu_matrix(size: tuple, scalar, dtype=torch.float) -> torch.Tensor:
    return torch.triu(torch.full(size, scalar, dtype=dtype))


def create_scalar_tril_matrix(size: tuple, scalar, dtype=torch.float) -> torch.Tensor:
    return torch.tril(torch.full(size, scalar, dtype=dtype))


def fill_vector(x: torch.Tensor, value) -> torch.Tensor:
    return x.fill_(value)


def expand_vector(x: torch.Tensor, size: tuple, value) -> torch.Tensor:
    """expand vector x to size"""
    return x.expand(size)


if __name__ == '__main__':
    size = (2, 3)
    x = create_vector(size)
    pass
